
import Database from "@tauri-apps/plugin-sql";

import { getG01DataBase, homePath } from '../../utils';

import { MetaDataObjectProperty, MetaDataObject, MetaDataObjectRelation } from '../types';

export const metaDataGetObjectProperties = async (objectIdentifier: string, page: number, pageSize: number,): Promise<{ total: number, data: Array<MetaDataObjectProperty> }> => {

    // _g01_meta_class_attributes
    const db = await getG01DataBase();

    let offset = (page - 1) * pageSize;

    let conditions = ` where object_identifier = $1 `;
    let args = [objectIdentifier];

    let count = (await db.select(`select count(1) cnt from _g01_meta_class_attributes ${conditions}`, args))[0].cnt;
    //
    let items: Array<any> = await db.select(`select * from _g01_meta_class_attributes ${conditions} order by id desc limit ${offset},${pageSize} `, args);
    console.log(items);
    if (items) {
        return {
            total: count,
            data: items.map((item, index) => objectPropertyDb2obj(item)),
        };
    }
    return {
        total: 0,
        data: []
    };
}

const objectPropertyDb2obj = (item: any): MetaDataObjectProperty => {
    return {
        id: item.id,
        objectIdentifier: item.object_identifier,
        identifier: item.identifier,
        name: item.name,
        isKey: item.is_key === 1,
        dataType: item.data_type,
        collectionType: item.collection_type,
        isNumber: item.is_number === 1,
        unit: item.unit,
        defaultValue: item.default_value,
        isNullable: item.is_nullable === 1,
        position: item.position,
        scope: item.scope,
        comment: item.comment,
        options: item.options,
        description: item.description,
    }
}


export const metaDataSaveObject = async (obj: MetaDataObject): Promise<number> => {

    // _g01_meta_class_attributes
    const db = await getG01DataBase();
    //
    if (obj.id > 0) {
        await db.execute(`update _g01_meta_classes set identifier = $1, name = $2, icon = $3, data_is_type = $4, description = $5 where id = $6`,
            [obj.identifier, obj.name, obj.icon, !!obj.dataIsType ? 1 : 0, obj.description, obj.id]);
        return 0;
    } else {
        await db.execute(`insert into _g01_meta_classes(domain_identifier,identifier,name,icon,data_is_type,description)Values($1,$2,$3,$4,$5,$6)`,
            [obj.domainIdentifier, obj.identifier, obj.name, obj.icon, !!obj.dataIsType ? 1 : 0, obj.description]);

        let res: Array<any> = await db.select('SELECT last_insert_rowid() nid');
        console.log(res);
        if (res && res.length > 0) {
            return res[0].nid;
        }
        return 0;
    }

}


export const metaDataUpdateObject = async (obj: MetaDataObject): Promise<number> => {

    // _g01_meta_class_attributes
    const db = await getG01DataBase();
    //
    await db.execute(`update _g01_meta_classes set name = $2, icon = $3, data_is_type = $4, description = $5 where identifier = $1`,
        [obj.identifier, obj.name, obj.icon, !!obj.dataIsType ? 1 : 0, obj.description]);
    return 0;
}


export const metaDataRemoveObject = async (objectId: number): Promise<void> => {

    // _g01_meta_class_attributes
    const db = await getG01DataBase();
    //
    if (objectId > 0) {
        await db.execute(`delete from _g01_meta_classes  where id = $1`, [objectId]);
    }

}


export const metaDataSaveObjectProperty = async (obj: MetaDataObjectProperty): Promise<number> => {

    // _g01_meta_class_attributes
    const db = await getG01DataBase();
    //
    await db.execute(`insert into _g01_meta_class_attributes(object_identifier,identifier,name,is_key,data_type,collection_type,is_number,unit,default_value,is_nullable,position,scope,comment,options,description)Values($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15)`,
        [obj.objectIdentifier, obj.identifier, obj.name, obj.isKey ? 1 : 0, obj.dataType, obj.collectionType, obj.isNumber ? 1 : 0, obj.unit, obj.defaultValue, obj.isNullable ? 1 : 0, obj.position, obj.scope, obj.comment, obj.options, obj.description]);

    let res: Array<any> = await db.select('SELECT last_insert_rowid() nid');
    console.log(res);
    if (res && res.length > 0) {
        return res[0].nid;
    }
    return 0;

}

export const metaDataUpdateObjectProperty = async (obj: MetaDataObjectProperty): Promise<number> => {

    // _g01_meta_class_attributes
    const db = await getG01DataBase();
    //
    await db.execute(`update _g01_meta_class_attributes set name = $2, is_key = $3, data_type = $4, is_number = $5, unit = $6, description = $7 where identifier = $1`,
        [obj.identifier, obj.name, obj.isKey ? 1 : 0, obj.dataType, obj.isNumber ? 1 : 0, obj.unit, obj.description]);
    return 0;

}

export const metaDataRemoveObjectProperty = async (propertyId: number): Promise<void> => {

    // _g01_meta_class_attributes
    const db = await getG01DataBase();
    //
    if (propertyId > 0) {
        await db.execute(`delete from _g01_meta_class_attributes  where id = $1`, [propertyId]);
    }

}


////
export const metaDataGetObjectRelationsByType = async (objectIdentifier: string, relationType: string): Promise<Array<MetaDataObjectRelation>> => {

    // _g01_meta_class_attributes
    const db = await getG01DataBase();
    //
    let items: Array<any> = await db.select(`select DISTINCT t.*, os.name src_object_name, os.icon src_object_icon, ot.name target_object_name, ot.icon target_object_icon  from _g01_meta_class_relations t, (select identifier from  _g01_meta_relations where relation_type = $1) r,_g01_meta_classes os,_g01_meta_classes ot where t.relation_identifier = r.identifier and (t.src_identifier = $2 or t.target_identifier = $2)  and t.src_identifier = os.identifier and t.target_identifier = ot.identifier `, [relationType, objectIdentifier]);
    if (items) {
        //
        return items.map((item, index) => {
            return {
                id: item.id,
                srcObjectName: item.src_object_name,
                srcObjectIcon: item.src_object_icon,
                targetObjectName: item.target_object_name,
                targetObjectIcon: item.target_object_icon,
                relationIdentifier: item.relation_identifier,
                srcIdentifier: item.src_identifier,
                targetIdentifier: item.target_identifier,
                srcCount: item.src_count,
                targetCount: item.target_count,
                relationProperties: item.relation_properties,
                description: item.description,
            }
        });
    }
    return [];
}

////
export const metaDataGetObjectRelations = async (objectIdentifier: string, relationType: string, isSrc: boolean): Promise<Array<MetaDataObjectRelation>> => {

    // _g01_meta_class_attributes
    const db = await getG01DataBase();
    //
    let identifierKey = 'target_identifier';

    if (isSrc) {
        identifierKey = 'src_identifier';
    }
    let items: Array<any> = await db.select(`select DISTINCT t.*, os.name src_object_name, os.icon src_object_icon, ot.name target_object_name, ot.icon target_object_icon from _g01_meta_class_relations t, (select identifier from  _g01_meta_relations where relation_type = $1) r,_g01_meta_classes os,_g01_meta_classes ot where t.relation_identifier = r.identifier and t.${identifierKey} = $2  and t.src_identifier = os.identifier and t.target_identifier = ot.identifier `, [relationType, objectIdentifier]);
    if (items) {
        //
        return items.map((item, index) => {
            return {
                id: item.id,
                srcObjectName: item.src_object_name,
                srcObjectIcon: item.src_object_icon,
                targetObjectName: item.target_object_name,
                targetObjectIcon: item.target_object_icon,
                relationIdentifier: item.relation_identifier,
                srcIdentifier: item.src_identifier,
                targetIdentifier: item.target_identifier,
                srcCount: item.src_count,
                targetCount: item.target_count,
                relationProperties: item.relation_properties,
                description: item.description,
            }
        });
    }
    return [];
}


export default {};